package org.kl.bpm.operation;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.IdentityService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.runtime.ProcessInstance;
import org.kl.bf.utils.ApplicationContextHelper;
import org.kl.bf.web.base.BasicController;
import org.kl.bpm.cmd.FindStartFormCmd;
import org.kl.bpm.entity.conf.BpmConfForm;
import org.kl.bpm.entity.conf.BpmFormTemplate;
import org.kl.bpm.entity.conf.BpmKvProp;
import org.kl.bpm.entity.conf.BpmKvRecord;
import org.kl.bpm.entity.conf.BpmProcess;
import org.kl.bpm.service.conf.BpmConfFormService;
import org.kl.bpm.service.conf.BpmFormTemplateService;
import org.kl.bpm.service.conf.BpmKvRecordService;
import org.kl.bpm.service.conf.BpmProcessService;
import org.kl.bpm.service.conf.BpmTaskConfService;
import org.kl.bpm.support.FormInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springside.modules.mapper.JsonMapper;

/**
 * 发起流程.
 */
public class StartProcessOperation extends AbstractOperation<Void> {
	private static Logger logger = LoggerFactory.getLogger(StartProcessOperation.class);
	public static final String OPERATION_TASK_ID = "taskId";
	public static final String OPERATION_BPM_PROCESS_ID = "bpmProcessId";
	public static final String OPERATION_COMMENT = "完成";
	public static final int STATUS_DRAFT_PROCESS = 0;
	public static final int STATUS_DRAFT_TASK = 1;
	public static final int STATUS_RUNNING = 2;
	private JsonMapper jsonMapper = new JsonMapper();

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public Void execute(CommandContext commandContext) {
		ProcessEngine processEngine = getProcessEngine();
		BpmFormTemplateService formTemplateService = getBpmFormTemplateService();
		BpmConfFormService bpmConfFormService = getBpmConfFormService();
		BpmKvRecordService bpmKvRecordService = getBpmKvRecordService();
		String bpmProcessId = getParameter(OPERATION_BPM_PROCESS_ID);
		BpmProcess bpmProcess = getBpmProcessService().getBpmProcess(bpmProcessId);
		String processDefinitionId = bpmProcess.getBpmConfBase().getProcessDefinitionId();

		// 先保存草稿
		String businessKey = new ConfAssigneeOperation().execute(getParameters());

		// 先设置登录用户
		IdentityService identityService = processEngine.getIdentityService();
		identityService.setAuthenticatedUserId(BasicController.getCurrentUserId());

		// 获得form的信息
		FormInfo formInfo = new FindStartFormCmd(processDefinitionId).execute(commandContext);

		// 尝试根据表单里字段的类型，进行转换
		Map<String, String> formTypeMap = new HashMap<String, String>();

		if (formInfo.isFormExists()) {
			BpmConfForm bpmConfForm = bpmConfFormService.findByBpmConfNodeBpmConfBaseProcessDefinitionIdAndBpmConfNodeCode(
					processDefinitionId, formInfo.getNodeCode());
			BpmFormTemplate formTemplate = formTemplateService.getBpmFormTemplate(bpmConfForm.getValue());
			String content = formTemplate.getContent();
			logger.debug("content : {}", content);
			Map map = jsonMapper.fromJson(content, Map.class);
			logger.debug("map : {}", map);
			List<Map> list = (List<Map>) map.get("fields");
			logger.debug("list : {}", list);
			for (Map item : list) {
				formTypeMap.put((String) item.get("name"), (String) item.get("type"));
			}
		}

		BpmKvRecord record = bpmKvRecordService.getBpmKvRecord(businessKey);

		Map<String, Object> processParameters = new HashMap<String, Object>();

		// 如果有表单，就从数据库获取数据
		for (BpmKvProp prop : record.getBpmKvProps()) {
			String key = prop.getCode();
			String value = prop.getValue();
			String formType = this.getFormType(formTypeMap, key);

			if ("userPicker".equals(formType)) {
				processParameters.put(key, new ArrayList(Arrays.asList(value.split(","))));
			} else if (formType != null) {
				processParameters.put(key, value);
			}
		}

		ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceById(processDefinitionId, businessKey,
				processParameters);
		record = new RecordBuilder().build(record, STATUS_RUNNING, processInstance.getId());
		bpmKvRecordService.saveBpmKvRecord(record);

		return null;
	}

	/**
	 * 工具方法，获取表单的类型.
	 */
	private String getFormType(Map<String, String> formTypeMap, String name) {
		if (formTypeMap.containsKey(name)) {
			return formTypeMap.get(name);
		} else {
			return null;
		}
	}

	public BpmFormTemplateService getBpmFormTemplateService() {
		return ApplicationContextHelper.getBean(BpmFormTemplateService.class);
	}

	public BpmConfFormService getBpmConfFormService() {
		return ApplicationContextHelper.getBean(BpmConfFormService.class);
	}

	public BpmKvRecordService getBpmKvRecordService() {
		return ApplicationContextHelper.getBean(BpmKvRecordService.class);
	}

	public BpmTaskConfService getBpmTaskConfService() {
		return ApplicationContextHelper.getBean(BpmTaskConfService.class);
	}

	public BpmProcessService getBpmProcessService() {
		return ApplicationContextHelper.getBean(BpmProcessService.class);
	}
}
